package com.gframework.mybatis.dao.mybatis.provider;

import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Map;

import com.gframework.util.GUtils;

/**
 * mybatis Provider的sql生成辅助工具类，使用此工具类可以将xml驱动中存在的一些比较快捷方便的标签以非xml的形式使用。
 * 
 * @since 1.0.0
 * @author Ghwolf
 */
public class ProviderSQLUtils {
	private ProviderSQLUtils(){}

	/**
	 * foreach循环生成sql，如果collection为null或无数据，则返回空字符串，如果其中存在空对象，则跳过。
	 * 其他相关参数也可以为null，如果param为null，那么参数将不会被设置到param中。
	 * 
	 * @param collection 集合对象
	 * @param start sql前缀
	 * @param end sql后缀
	 * @param separator 分隔符
	 * @param item 每一项的参数名称，类似xml中的foreach的item
	 * @param param 存放参数的对象
	 * @return 返回sql语句
	 */
	public static String foreach(Collection<?> collection, String start, String end, String separator, String item,
			Map<String, Object> param) {
		if (collection == null || collection.isEmpty()) return "";
		if (start == null) start = "";
		if (end == null) end = "";
		if (separator == null) separator = " ";
		if (item == null) item = "item";

		StringBuilder sql = new StringBuilder(start);
		int index = 0;
		for (Object obj : collection) {
			if (obj == null) continue;
			String n = generatorParamName(item, index ++);
			sql.append("#{").append(n).append('}').append(separator);
			if (param != null) {
				param.put(n, obj);
			}
		}
		return sql.delete(sql.length() - separator.length(), sql.length()).append(end).toString();
	}

	/**
	 * foreach循环生成sql，如果collection为null或无数据，则返回空字符串，如果其中存在空对象，则跳过。
	 * 其他相关参数也可以为null，如果param为null，那么参数将不会被设置到param中。
	 * 
	 * @param array 数组对象
	 * @param start sql前缀
	 * @param end sql后缀
	 * @param separator 分隔符
	 * @param item 每一项的参数名称，类似xml中的foreach的item
	 * @param param 存放参数的对象，不能为null
	 * @return 返回sql语句
	 */
	public static String foreach(Object[] array, String start, String end, String separator, String item,
			Map<String, Object> param) {
		if (array == null || array.length == 0) return "";
		if (start == null) start = "";
		if (end == null) end = "";
		if (separator == null) separator = " ";
		if (item == null) item = "item";

		StringBuilder sql = new StringBuilder(start);
		int index = 0;
		for (int x = 0; x < array.length; x ++) {
			Object obj = array[x];
			if (obj == null) continue ;
			String n = generatorParamName(item, index ++);
			sql.append("#{").append(n).append('}').append(separator);
			param.put(n, obj);
		}
		return sql.delete(sql.length() - separator.length(), sql.length()).append(end).toString();
	}
	/**
	 * foreach循环生成sql，如果collection为null或无数据，则返回空字符串，如果其中存在空对象，则跳过。
	 * 其他相关参数也可以为null，如果param为null，那么参数将不会被设置到param中。
	 * <p>
	 * 此方法会对可能是数组的对象进行处理，如果你取得的是一个不确定类型的数组对象，那么可以使用此方法生成。
	 * </p>
	 * 
	 * @param array 数组对象
	 * @param start sql前缀
	 * @param end sql后缀
	 * @param separator 分隔符
	 * @param item 每一项的参数名称，类似xml中的foreach的item
	 * @param param 存放参数的对象，不能为null
	 * @return 返回sql语句
	 */
	public static String foreach(Object array, String start, String end, String separator, String item,
			Map<String, Object> param) {
		if (array == null || !array.getClass().isArray() || Array.getLength(array) == 0) return "";
		if (start == null) start = "";
		if (end == null) end = "";
		String[] _separator = new String[]{separator == null ? " " : separator};
		String[] _item = new String[]{item == null ? "item" : item};
		
			StringBuilder sql = new StringBuilder(start);
		final int[] index = new int[]{0};
		GUtils.arrayForeach(array, obj -> {
			if (obj == null) return;
			String n = generatorParamName(_item[0], index[0] ++);
			sql.append("#{").append(n).append('}').append(_separator[0]);
			param.put(n, obj);
		});
		return sql.delete(sql.length() - _separator[0].length(), sql.length()).append(end).toString();
	}
	
	/**
	 * 生成不会重复的参数名称
	 */
	public static String generatorParamName(String item, int index) {
		return "!" + item + index;
	}
	
	/**
	 * 生成不会重复的参数名称
	 */
	public static String generatorParamName(int index) {
		return "!" + index ;
	}

}
